package com.baozun.controller;

import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.baozun.model.TFindMail;
import com.baozun.model.TFindMailExample;
import com.baozun.model.TFriend;
import com.baozun.model.TFriendExample;
import com.baozun.model.TUser;
import com.baozun.model.TUserExample;
import com.baozun.model.TWorkrecord;
import com.baozun.model.TWorkrecordExample;
import com.baozun.service.FindMailService;
import com.baozun.service.FriendService;
import com.baozun.service.UserService;
import com.baozun.service.WorkrecordService;
import com.baozun.util.AjaxUtil;
import com.baozun.util.CommonConst;
import com.baozun.util.CookieUtil;
import com.baozun.util.DataEncapsulation;
import com.baozun.util.MD5Util;
import com.baozun.util.ModelAndViewUtil;
import com.baozun.util.ModelExampleUtil;
import com.baozun.util.ReloadablePropertiesUtil;
import com.baozun.util.SessionUtil;
import com.baozun.util.Tools;
import com.baozun.util.WebUtil;

/**
 * 
 * @Title:
 * @Company:宝尊电子商务有限公司
 * @Author:万世极缘
 * @Since:2014-12-28
 * @Copyright:Copyright (c) 2014
 * @ModifyDate:2014-12-28
 * @Version:1.1.0
 */
@Controller
public class LoginController {
    
    @Autowired
    @Qualifier("userService")
    private UserService userService;
    @Autowired
    @Qualifier("findMailService")
    private FindMailService findMailService;
    @Autowired
    @Qualifier("workrecordCongifService")
    private ReloadablePropertiesUtil workrecordCongifService;
    @Autowired
    private WorkrecordService workrecordService;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private FriendService friendService;
    
    /**
     * 登录界面
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = {"/login", "/login.php", "/login.html"})
    public ModelAndView login(HttpServletRequest request, HttpServletResponse response) {
        return new ModelAndView("login");
    }
    
    /**
     * 
     * @param request
     * @param response
     * @return
     * @Description:
     */
    @RequestMapping("/logout")
    public ModelAndView logout(HttpServletRequest request, HttpServletResponse response) {
        SessionUtil.remove(request, CommonConst.SESSION_USER);
        return new ModelAndView("login");
    }
    
    /**
     * 登录提交
     * 
     * @param request
     * @param response
     * @param stUsername
     * @param stPassword
     * @return
     */
    @RequestMapping("/login_submit")
    public ModelAndView loginSubmit(HttpServletRequest request, HttpServletResponse response, @RequestParam("stUsername") String stUsername, @RequestParam("stPassword") String stPassword) {
        /** 是否记住用户 *****************************************/
        String rememberMe = request.getParameter(CommonConst.COOKIE_REMEMBER_ME);
        int maxAge = workrecordCongifService.loadInteger("cookie.maxAge");
        if ("on".equals(rememberMe)) {
            CookieUtil.addCookie(response, CommonConst.COOKIE_REMEMBER_ME, rememberMe, maxAge);
            CookieUtil.addCookie(response, CommonConst.COOKIE_USERNAME, stUsername, maxAge);
            CookieUtil.addCookie(response, CommonConst.COOKIE_PASSWORD, stPassword, maxAge);
        } else {
            CookieUtil.deleteCookie(request, response, CommonConst.COOKIE_REMEMBER_ME);
            CookieUtil.deleteCookie(request, response, CommonConst.COOKIE_USERNAME);
            CookieUtil.deleteCookie(request, response, CommonConst.COOKIE_PASSWORD);
        }
        /******************************************************/
        TUser user = userService.getByUsername(stUsername);
        /** 跳转 *****************/
        Map<String, Object> model = new HashMap<String, Object>();
        String url = "";
        // 判断跳转地址，以及得到反馈信息
        if (Tools.isNotEmpty(user)) {
            String userStPassword = user.getStPassword();
            if (MD5Util.getMD5String(stPassword).equalsIgnoreCase(userStPassword)) {
                url = "index";
                SessionUtil.setSession(request, CommonConst.SESSION_USER, user);
            } else {
                url = "login";
                model.put("message", WebUtil.encodeURL("用户名或密码错误!"));
            }
        } else {
            url = "login";
            model.put("message", WebUtil.encodeURL("用户名或密码错误!"));
        }
        // 因为是重定向，所以要经过WebUtil进行编码处理
        return new ModelAndViewUtil().setModel(model).toRedirectUrl(url);
    }
    
    @RequestMapping("/index")
    public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
        // 从session中取出用户
        TUser user = SessionUtil.getAttribute(request, CommonConst.SESSION_USER, TUser.class);
        Map<String, Object> model = new HashMap<String, Object>();
        /** 从数据库中查询用户名对应的用户数据 ******************/
        // 查询被请求的交友信息(stUserIdRequest = stUserId and stStatus = "0")
        TFriendExample friendRecord = new TFriendExample();
        friendRecord.createCriteria().andStUserIdResponseEqualTo(user.getStUserId()).andStStatusEqualTo(CommonConst.BOOLEAN_VALUE_FALSE_STR);
        List<TFriend> friendRequestList = friendService.getList(friendRecord);
        model.put("friendRequestCount", friendRequestList.size());
        model.put("friendRequestList", friendRequestList);
        // 查询未完成工作
        TWorkrecordExample workrecordRecord = new TWorkrecordExample();
        workrecordRecord.createCriteria().andStUserIdEqualTo(user.getStUserId()).andStFinishLevelBetween("1", "2");
        List<TWorkrecord> workrecordList = workrecordService.getList(workrecordRecord);
        model.put("workrecordUnfinishedCount", workrecordList.size());
        model.put("workrecordUnfinishedList", workrecordList);
        /*** 初始数据处理完毕 *****************************************/
        return new ModelAndViewUtil().setModel(model).toUrl("index");
    }
    
    /**
     * ajax login_submit
     * 
     * @param request
     * @param response
     * @param stUsername
     * @param stPassword
     * @return
     */
    @RequestMapping("/ajax_login_submit")
    public void ajaxLoginSubmit(HttpServletRequest request, HttpServletResponse response, @RequestParam("stUsername") String stUsername, @RequestParam("stPassword") String stPassword) {
        // 从数据库中查询用户名对应的用户数据
        PrintWriter out = AjaxUtil.getWriter(request, response);
        TUser user = userService.getByUsername(stUsername);
        String userStPassword = user.getStPassword();
        if (stPassword.equalsIgnoreCase(userStPassword)) {
            out.println(CommonConst.AJAX_RIGHT);
        } else {
            out.println(CommonConst.AJAX_ERROR);
        }
    }
    
    /**
     * 注册提交数据
     * 
     * @param request
     * @param response
     * @Description:
     */
    @RequestMapping("/registe")
    public String registeController(ModelMap model, HttpServletRequest request, HttpServletResponse response, @RequestParam("stPassword") String stPassword) {
        try {
            // 将request提交的数据封装到user中
            TUser user = DataEncapsulation.request2Bean(request, TUser.class);
            // 密码转换（获取字符串的md5值）
            user.setStPassword(MD5Util.getMD5String(stPassword));
            userService.add(user);
            return "login";
        } catch (Exception e) {
            e.printStackTrace();
            model.put("msg", "注册失败请重试！");
            return "login";
        }
    }
    
    /**
     * ajax检测数据可用性
     * 
     * @param request
     * @param response
     * @Description:
     */
    @RequestMapping("/check_usabled")
    public void checkUsabled(HttpServletRequest request, HttpServletResponse response) {
        // 得到jsp界面输出
        PrintWriter out = AjaxUtil.getWriter(request, response);
        
        try {
            // 将信息转成用户对象
            TUser user = DataEncapsulation.request2Bean(request, TUser.class);
            TUserExample record = new TUserExample();
            record.or(ModelExampleUtil.getCriteriaByModel(user, TUserExample.Criteria.class));
            
            // 根据用户模型查询对象
            List<TUser> userList = userService.getList(record);
            if (CollectionUtils.isEmpty(userList)) {
                // 该用户可以使用
                out.print(CommonConst.AJAX_RIGHT);
            } else {
                out.print(CommonConst.AJAX_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            out.print(CommonConst.AJAX_ERROR);
        }
        out.flush();
        out.close();
    }
    
    @RequestMapping("/forget_password_submit")
    public void forgetPasswordSubmit(HttpServletRequest request, HttpServletResponse response, @RequestParam("stEmail") String stEmail, @RequestParam("stUsername") String stUsername) throws MessagingException {
        PrintWriter out = AjaxUtil.getWriter(request, response);
        // 通过用户名进行查找
        TUser user = userService.getByUsername(stUsername);
        if (stEmail.equals(user.getStEmail())) {
            // 先在findmail中是否存在重复
            TFindMailExample record = new TFindMailExample();
            TFindMailExample.Criteria criteria = record.createCriteria();
            criteria.andStEmailEqualTo(stEmail);
            criteria.andStUserIdEqualTo(user.getStUserId());
            List<TFindMail> findMailList = findMailService.getList(record);
            TFindMail findMail = null;
            if (CollectionUtils.isEmpty(findMailList)) {
                // 如果为空生成邮箱验证
                findMail = createMail(workrecordCongifService.loadString("mail.smtp.username"), stEmail, user.getStUserId(), stUsername);
                findMailService.add(findMail);
            } else {
                findMail = findMailList.get(0);
            }
            //
            MimeMessage mime = mailSender.createMimeMessage();
            MimeMessageHelper mimehelper = new MimeMessageHelper(mime, true, "UTF-8");
            mimehelper.setFrom(findMail.getStFrom());// 设置发送人
            mimehelper.setTo(findMail.getStTo());// 设置收件人
            // if (mail.getCopyTo() != null && !"".equals(mail.getCopyTo())){
            // mimehelper.setCc(mail.getCopyTo());// 设置抄送人
            // }
            // if (mail.getHideCopyTo() != null && !"".equals(mail.getHideCopyTo())){
            // mimehelper.setBcc(mail.getHideCopyTo());// 设置暗送人
            // }
            mimehelper.setSentDate(new Date());// 设置发送日期
            mimehelper.setSubject(findMail.getStSubject());// 设置主题
            mimehelper.setText(findMail.getClContent(), true);// 设置邮件内容为HTML超文本格式
            mailSender.send(mime);// 将邮件发送
            out.print(CommonConst.AJAX_RIGHT);
        } else {
            // 反馈信息
            out.print(CommonConst.AJAX_ERROR);
        }
    }
    
    /**
     * 
     * @param request
     * @param response
     * @return
     * @Description:
     */
    @RequestMapping("/find_password_submit")
    public ModelAndView findPassword(HttpServletRequest request, HttpServletResponse response) {
        String stEmail = request.getParameter("stEmail");
        String stUsername = request.getParameter("stUsername");
        String stPassword = request.getParameter(TUser.ST_PASSWORD);
        String stCheckCode = request.getParameter("stCheckCode");
        TUser user = userService.getByUsername(stUsername);
        String message = "";
        String type = "";
        boolean isRight = false;
        String view = "find_password";
        String md5 = MD5Util.getMD5String(stPassword);
        if (StringUtils.isNotEmpty(stEmail) && StringUtils.isNotEmpty(stUsername) && StringUtils.isNotEmpty(stCheckCode)) {
            isRight = true;
        }
        if (isRight) {
            // 从find_mail中查询是否存在该密码验证
            TFindMailExample record = new TFindMailExample();
            TFindMailExample.Criteria criteria = record.createCriteria();
            criteria.andStEmailEqualTo(stEmail);
            criteria.andStCheckCodeEqualTo(stCheckCode);
            criteria.andStUserIdEqualTo(user.getStUserId());
            List<TFindMail> findMailList = findMailService.getList(record);
            if (CollectionUtils.isEmpty(findMailList)) {
                // 如果为空，表示并没有提交忘记密码操作，为非法提交
                message = "非法链接！";
                type = CommonConst.BOOLEAN_VALUE_FALSE_STR;// 错误
            } else {
                TFindMail findMail = findMailList.get(0);// 得到忘记密码的数据
                String stStatus = findMail.getStStatus();// 处理状态
                if (CommonConst.WORK_FINISHED.equals(stStatus)) {
                    message = "该处理已过期！";
                    type = CommonConst.BOOLEAN_VALUE_FALSE_STR;
                } else {
                    // 有效
                    user.setStPassword(md5);
                    userService.update(user);
                    message = "修改成功，请使用新密码登录";
                    view = "login.jsp";
                    type = CommonConst.BOOLEAN_VALUE_TRUE_STR;
                }
            }
        } else {
            message = "非法链接";
            type = CommonConst.BOOLEAN_VALUE_FALSE_STR;// 错误
        }
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("message", message);
        // 重新加载参数，进入的是密码找回界面
        if (CommonConst.BOOLEAN_VALUE_FALSE_STR.equals(type)) {
            model.put(TUser.ST_EMAIL, stEmail);
            model.put(TUser.ST_USERNAME, stUsername);
            model.put(TFindMail.ST_CHECK_CODE, stCheckCode);
        }
        return new ModelAndViewUtil().setModel(model).toUrl(view);
    }
    
    /**
     * 
     * @param from
     * @param to
     * @return
     * @Description:
     */
    private TFindMail createMail(String from, String stEmail, String stUserId, String stUsername) {
        // TODO Auto-generated method stub
        TFindMail mail = new TFindMail();
        StringBuffer sb = new StringBuffer();
        mail.setStUserId(stUserId);
        mail.setStEmail(stEmail);
        mail.setStFrom(from);
        mail.setStTo(stEmail);
        mail.setStSubject("工作日志系统密码找回，收到此邮件请勿回复");
        mail.setStStatus(CommonConst.WORK_UNFINISH);
        mail.setStCheckCode(UUID.randomUUID().toString());
        sb.append("<div style=\"color:#000000;font-family:微软雅黑;font-style:normal;font-weight:normal;background-color:#FFFFFF;text-align:center;font-size:19px;\"><b><span style=\"color:#E53333;\">密码找回</span></b></div>");
        sb.append("<div style=\"color:#000000;font-family:微软雅黑;font-size:medium;font-style:normal;font-weight:normal;background-color:#FFFFFF;text-align:center;\">");
        sb.append("<span>您的用户为:").append(stUsername).append(",邮箱为:").append(stEmail).append(",请点击:<a href=\"http://localhost:7777/WorkRecord/find_password.jsp?stUsername=").append(stUsername).append("&stEmail=").append(stEmail).append("&stCheckCode=")
                .append(mail.getStCheckCode()).append("\">找回密码</a>，重置您的密码。</span>");
        sb.append("</div>");
        sb.append("<div style=\"color:#000000;font-family:微软雅黑;font-size:medium;font-style:normal;font-weight:normal;background-color:#FFFFFF;text-align:center;\">");
        sb.append("<span><br />");
        sb.append("</span>");
        sb.append("</div>");
        sb.append("<div style=\"color:#000000;font-family:微软雅黑;font-size:medium;font-style:normal;font-weight:normal;background-color:#FFFFFF;text-align:left;\">");
        sb.append("<span>本邮件由工作日志系统发出，请勿回复！</span>");
        sb.append("</div>");
        mail.setClContent(sb.toString());
        return mail;
    }
}
